package cn.yunyichina.provider.register.service.impl;

import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.HisifaceService;
import cn.yunyichina.provider.framework.dubbo.service.MessageService;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.base.Org;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.hisiface.BaseVo;
import cn.yunyichina.provider.iface.entity.hisiface.register.*;
import cn.yunyichina.provider.register.dao.ReserveDao;
import cn.yunyichina.provider.register.entity.Reserve;
import cn.yunyichina.provider.register.utils.RegUtil;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.log.Log;
import cn.yunyichina.utils.log.constant.LogParamType;
import cn.yunyichina.utils.log.constant.LogScene;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 预约取号
 * @author hezuzhi
 * @Description: ()
 * @date 2017-05-05  10:39.
 * @version: 1.0
 */
@Service
public class RegReserveServiceImpl {
    private Logger logger = LoggerFactory.getLogger(RegReserveServiceImpl.class);

    @Autowired
    ReserveDao reserveDao ;

    /**
     * 预约资料查询 yyt.register.reg.order.data.get --> yyt.register.reg.reserve.record.list
     *
     * @param data
     * @param sessionId
     * @return
     */
    public Response listRegReserveRecord(String data, String sessionId) {
//        logger.info("listRegReserveRecord, request data=" + data + ", sessionId=" + sessionId);
        Log.i(LogScene.REGISTER_RESERVE,"yyt.register.reg.reserve.record.list", LogParamType.REQUEST,"", data);
        Response response = new Response();


        OrderDataVo orderDataVo = JsonUtils.parseObject(data, OrderDataVo.class);
        if(StringUtils.isNotBlank(orderDataVo.getReserveNo())){
            orderDataVo.setOrderNo(orderDataVo.getReserveNo());
        }
        if(StringUtils.isNotBlank(orderDataVo.getPatIdNo())){
            orderDataVo.setIdCardNo(orderDataVo.getPatIdNo());
        }


//        logger.info("listRegReserveRecord request=" + JSONObject.toJSONString(orderDataVo));
        Log.i(LogScene.REGISTER_RESERVE,"yyt.register.reg.reserve.record.list", LogParamType.REQUEST,orderDataVo.getReserveNo(),
                "call hisiface getRegisterOrderDataList request=" + JSONObject.toJSONString(orderDataVo));
        ResCommon  orderResponse;
        if("gzszcqrmyy".equals(orderDataVo.getHospitalCode()) || "fgrmyy".equals(orderDataVo.getHospitalCode())){
            orderResponse = HisifaceService.getHisifaceClient().getRegisterOrderDataList(orderDataVo);
//            logger.info("listRegReserveRecord, response=" + JSONObject.toJSONString(orderResponse));
            Log.i(LogScene.REGISTER_RESERVE,"yyt.register.reg.reserve.record.list", LogParamType.REQUEST,orderDataVo.getReserveNo(),
                    "call hisiface getRegisterOrderDataList response=" + JSONObject.toJSONString(orderResponse));
            if (!ResCommon.SUCCESS_CODE.equals(orderResponse.getResultCode())) {
                response.setResultCodeAndMessage(orderResponse.getResultCode(), orderResponse.getResultMessage());
                return response;
            }
            List<OrderDataVoResponse> infoVoResponses = JsonUtils.parseArray(JsonUtils.toJsonString(orderResponse.getResult()), OrderDataVoResponse.class);
            if (CollectionUtils.isEmpty(infoVoResponses)) {
                response.setResultCodeAndMessage("6003", "暂无预约资料信息！");
                return response;
            } else {
                response.setResultCodeAndMessage("0", "成功");
                response.setResult(JsonUtils.toJsonString(infoVoResponses));
                //插入预约资料查询结果
                for(OrderDataVoResponse responseItem : infoVoResponses){
                    insertReserve(orderDataVo,responseItem);
                }
            }
        }else {
            orderResponse = HisifaceService.getHisifaceClient().getRegisterOrderData(orderDataVo);
            Log.i(LogScene.REGISTER_RESERVE,"yyt.register.reg.reserve.record.list", LogParamType.REQUEST,orderDataVo.getReserveNo(),
                    "call hisiface getRegisterOrderData response=" + JSONObject.toJSONString(orderResponse));
            if (!ResCommon.SUCCESS_CODE.equals(orderResponse.getResultCode())) {
                response.setResultCodeAndMessage(orderResponse.getResultCode(), orderResponse.getResultMessage() );
                return response;
            }

            OrderDataVoResponse infoVoResponses = JsonUtils.parseObject(orderResponse.getResult(), OrderDataVoResponse.class);
            if (infoVoResponses == null) {
                response.setResultCodeAndMessage("6003", "暂无预约资料信息！");
                return response;
            } else {
                response.setResultCodeAndMessage("0", "成功");
                response.setResult(JsonUtils.toJsonString(infoVoResponses));
                //插入预约资料查询结果
                insertReserve(orderDataVo,infoVoResponses);
            }

            /**************取号规则判断********/
            String reservationRule[] = RegUtil.getRule(orderDataVo.getHospitalCode(),RegUtil.RESERVATION_RULE,"1").split(",");
            String beginTime=infoVoResponses.getBeginTime();
            String endTime=infoVoResponses.getEndTime();
            if(StringUtils.isBlank(beginTime)){
                if("2".equals(infoVoResponses.getTimeFlag())){
                    //下午的号源
                    beginTime="12:00:00";
                }else{
                    beginTime="00:00:00";
                }
            }else{
                beginTime += ":00";
            }
            if(StringUtils.isBlank(endTime)){
                if("1".equals(infoVoResponses.getTimeFlag())){
                    endTime="12:00:00";
                }else{
                    endTime="23:59:00";
                }
            }else{
                endTime += ":00";
            }
            Date scheduleBegin = DateUtils.StringToDate(infoVoResponses.getScheduleDate() + " " + beginTime);
            Date scheduleEnd = DateUtils.StringToDate(infoVoResponses.getScheduleDate() + " " + endTime);

            Date now = new Date();
            if (now.after(scheduleEnd)) {
                response.setResultCodeAndMessage("6003", "您的号源已过期！");
                return response;
            }
            if(DateUtils.StringToDateYMD(DateUtils.getDateStr(now) + " 00:00:00").after(scheduleBegin)){
                response.setResultCodeAndMessage("6004", "请在预约号源当天取号！");
                return response;
            }
            if(reservationRule.length ==2 ){
                if(reservationRule[0].equals("2")) {
                    //当班几点之后才能取号
                    Date reservationRuleDate = DateUtils.StringToDate(DateUtils.getDateStr(now) + " " + reservationRule[1] + ":00");
                    if (now.before(reservationRuleDate)) {
                        response.setResultCodeAndMessage("6005", "还未到取号时间，请在" + reservationRule[1] + "点后再次尝试取号");
                        return response;
                    }
                }
            }
            if(reservationRule!=null && reservationRule[0].equals("3")){
                //3：上午不能取下午的号源
                Date middayDate =  DateUtils.StringToDate(DateUtils.getDateStr(now) + " 12:00:00");
                if(now.before(middayDate) && scheduleBegin.after(middayDate)){
                    response.setResultCodeAndMessage("6006", "您预约的是下午号源，请在12：00之后取号");
                    return response;
                }
            }
            /**************取号规则判断end********/

        }
        return response;
    }

    /**
     * 预约资料查询(直接转调调度中心) yyt.register.reg.reserve.record.get
     *
     * @param data
     * @param sessionId
     * @return
     */
    public Response getRegReserveRecord(String data, String sessionId) {
        logger.info("预约资料查询(直接转调调度中心), data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();

        OrderDataVo orderDataVo = JsonUtils.parseObject(data, OrderDataVo.class);

        logger.info("预约资料查询(直接转调调度中心) request=" + JSONObject.toJSONString(orderDataVo));
        ResCommon  orderResponse;
        orderResponse = HisifaceService.getHisifaceClient().getRegisterOrderData(orderDataVo);
        logger.info("预约资料查询(直接转调调度中心), response=" + JSONObject.toJSONString(orderResponse));
        if (!ResCommon.SUCCESS_CODE.equals(orderResponse.getResultCode())) {
            response.setResultCodeAndMessage(orderResponse.getResultCode(), orderResponse.getResultMessage() );
            return response;
        }else{
            OrderDataVoResponse infoVoResponses = JsonUtils.parseObject(orderResponse.getResult(), OrderDataVoResponse.class);
            if (infoVoResponses == null) {
                response.setResultCodeAndMessage("6003", "暂无预约资料信息！");
                return response;
            } else {
                response.setResultCodeAndMessage("0", "成功");
                response.setResult(JsonUtils.toJsonString(infoVoResponses));
                return response;
            }
        }
    }

    /**
     * 保存预约资料查询结果
     * @param orderDataVo
     * @param infoVo
     */
    private void insertReserve(OrderDataVo orderDataVo,OrderDataVoResponse infoVo) {
        Reserve reserve = new Reserve();
        reserve.setId(PKGenerator.generateId());
        reserve.setPatIdNo(orderDataVo.getIdCardNo());
        reserve.setPatName(infoVo.getPatName());
        reserve.setReserveNo(orderDataVo.getOrderNo());
        reserve.setMedicalCardType(StringUtils.isNotBlank(infoVo.getPatCardType()) ? Short.parseShort(infoVo.getPatCardType()) : (short) 1);
        reserve.setMedicalCardNo(infoVo.getPatCardNo());
        reserve.setDeptCode(infoVo.getDeptCode());
        reserve.setDeptName(infoVo.getDeptName());
        reserve.setDoctorCode(infoVo.getDoctorCode());
        reserve.setDoctorName(infoVo.getDoctorName());
        reserve.setScheduleDate(infoVo.getScheduleDate());
        if(StringUtils.isNotBlank(infoVo.getTimeFlag())){
            reserve.setTimeFlag(Short.parseShort(infoVo.getTimeFlag()));
        }
        reserve.setBeginTime(infoVo.getBeginTime());
        reserve.setEndTime(infoVo.getEndTime());
        reserve.setWorkId(infoVo.getWorkId());
        reserve.setRegFee(infoVo.getRegFee() !=null?Integer.parseInt(infoVo.getRegFee()) : 0);
        reserve.setTreatFee(infoVo.getTreatFee() !=null?Integer.parseInt(infoVo.getTreatFee()) : 0);
        reserve.setSsTreatFee(infoVo.getSsTreatFee() !=null?Integer.parseInt(infoVo.getSsTreatFee()) : 0);
        reserve.setPayFlag(Short.parseShort(infoVo.getPayFlag()));
        reserve.setReceiptNum(infoVo.getReceiptNum());
        reserve.setSerialNum(infoVo.getSerialNum());
        reserve.setVisitLocation(infoVo.getVisitLocation());
        reserve.setOrderTime(infoVo.getOrderTime());

        reserve.setOrgCode(orderDataVo.getHospitalCode());
        reserve.setBranchCode(orderDataVo.getBranchCode());
        Org org = BaseService.getBaseClient().getOrgByCode(orderDataVo.getHospitalCode());
        if (org == null) {
           logger.error("没有org_code对应的机构信息:" + orderDataVo.getHospitalCode() + "！");
        }else{
            reserve.setOrgId(org.getId());
            reserve.setOrgName(org.getOrgName());
        }
        reserveDao.insert(reserve);

    }

    /**
     * 预约取号接口 yyt.register.reg.order.no.take  --> yyt.register.reg.reserve.record.take
     *
     * @param data
     * @param sessionId
     * @return
     */
    public Response takeRegReserveRecord(String data, String sessionId,String appId) {
        logger.info("takeRegReserveRecord, request data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();


        TakeNoVo takeNoVo = JsonUtils.parseObject(data, TakeNoVo.class);
        if(StringUtils.isNotBlank(takeNoVo.getReserveNo())){
            takeNoVo.setHisOrdNum(takeNoVo.getReserveNo());
        }
        if(StringUtils.isNotBlank(takeNoVo.getPatIdNo())){
            takeNoVo.setIdCardNo(takeNoVo.getPatIdNo());
        }
        Map<String, String> extraParamsMap = new HashMap<>();
        if(takeNoVo.getHospitalCode().indexOf("szsykyy") >=0 && appId.equals("yyt48fe49dbe6eb1cee")){
            extraParamsMap.put("channel","1");
        }else if(takeNoVo.getHospitalCode().indexOf("szsykyy") >=0 && appId.equals("yytcda5b2de00d8717c")){
            extraParamsMap.put("channel","2");
        }
        takeNoVo.setExtendParams(JsonUtils.toJsonString(extraParamsMap));
//        logger.info("takeRegReserveRecord request=" + JSONObject.toJSONString(takeNoVo));
        Log.i(LogScene.REGISTER_RESERVE,"yyt.register.reg.reserve.record.list", LogParamType.REQUEST,takeNoVo.getReserveNo(),
                "call hisiface takeRegReserveRecord request=" + JSONObject.toJSONString(takeNoVo));
        ResCommon<TakeNoVoResponse> takeNoVoResponse = HisifaceService.getHisifaceClient().takeRegisterNo(takeNoVo);
//        logger.info("takeRegReserveRecord, response=" + JSONObject.toJSONString(takeNoVoResponse));
        Log.i(LogScene.REGISTER_RESERVE,"yyt.register.reg.reserve.record.list", LogParamType.REQUEST,takeNoVo.getReserveNo(),
                "call hisiface takeRegReserveRecord response=" + JSONObject.toJSONString(takeNoVoResponse));

        if (!ResCommon.SUCCESS_CODE.equals(takeNoVoResponse.getResultCode())) {
            response.setResultCodeAndMessage(takeNoVoResponse.getResultCode(),takeNoVoResponse.getResultMessage());
            return response;
        }

        // 消息推送
        try {
            TakeNoVoResponse takeNoResp = takeNoVoResponse.getResult();
            Org org = BaseService.getBaseClient().getOrgByCode(takeNoVo.getHospitalCode());
            String method = "yyt.message.msg.template.send";

            Map<String,Object> dataMap = new HashedMap();
            dataMap.put("user_type","2");
            dataMap.put("to_user", takeNoVo.getOpenId());
//            dataMap.put("order_no",order.getOrderNo());
            dataMap.put("platform_type","2");
            dataMap.put("org_app_code",takeNoVo.getAppCode());
            dataMap.put("org_code",takeNoVo.getHospitalCode());
            dataMap.put("template_code","21002");
            Map<String,Object> msgContent = new HashedMap();
            msgContent.put("first","您已经成功取号。");
            msgContent.put("keyword1",takeNoVo.getPatName());
            msgContent.put("keyword2",takeNoResp.getDoctorName());
            msgContent.put("keyword3",takeNoResp.getDeptName());
            msgContent.put("keyword4",org.getOrgName());
            msgContent.put("keyword5",takeNoResp.getVisitTime());
            String remark = "排队号:" + takeNoResp.getSerialNum()
                    + "\n就诊地址:" + takeNoResp.getDeptLocation()
                    + "\n发票号:" + takeNoResp.getReceiptNum()
                    + "\n就诊说明:" + "";
            msgContent.put("remark",remark);
            dataMap.put("msg_content",JsonUtils.toJsonString(msgContent));
            Response messageResponse = MessageService.callHumpFromInternal(method, JsonUtils.toJsonString(dataMap));
            logger.info("取号成功 调用message模块, request={}，response={}",
                    JsonUtils.toJsonString(dataMap),JsonUtils.toJsonString(messageResponse));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("取号成功调用消息模块异常:", e.getMessage());
        }
        response.setResultCodeAndMessage("0", "成功");
        response.setResult(JsonUtils.toJsonString(takeNoVoResponse.getResult()));
        return response;
    }

    /**
     * 自动取号接口 yyt.register.reg.reserve.record.autotake
     *
     * @param data
     * @param sessionId
     * @return
     */
    public Response AutotakeRegReserveRecord(String data, String sessionId) {
        logger.info("AutotakeRegReserveRecord, request data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();


        TakeNoVo takeNoVo =  new TakeNoVo();
        takeNoVo.setHospitalCode("szsdermyy");
        ResCommon<List<AutoTakeNoVoResponse>> hisResponse = HisifaceService.getHisifaceClient().autoTakeRegisterNo(takeNoVo);

        Log.i(LogScene.REGISTER_RESERVE_AUTOTAKE,"yyt.register.reg.reserve.record.autotake", LogParamType.REQUEST,"",
                "call hisiface autoTakeRegisterNo response=" + JSONObject.toJSONString(hisResponse));

        if (!ResCommon.SUCCESS_CODE.equals(hisResponse.getResultCode())) {
            response.setResultCodeAndMessage(hisResponse.getResultCode(),hisResponse.getResultMessage());
            return response;
        }

        // 消息推送
        try {
            List<AutoTakeNoVoResponse> list = hisResponse.getResult();
            if(list == null || list.size() ==0 ){
                return response;
            }
            for(AutoTakeNoVoResponse takeNoVoResponse:list) {
                /**根据订单好查出订单对象**/
                Map<String, String> ordQueryMap = new HashMap<String, String>();
                ordQueryMap.put("order_no", takeNoVoResponse.getPsordnum());
                Response ordResponse = BaseService.callUnderlineFromInternal(sessionId,
                        "yyt.base.order.by.order.no.get", JsonUtils.toJsonString(ordQueryMap));
                if(!"0".equals(ordResponse.getResultCode())){
                    logger.error("查询订单失败 " + takeNoVoResponse.getPsordnum());
                    response.setResultCodeAndMessage("6000", "查询订单失败。");
                    return response;
                }
                OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
                /**根据订单好查出订单对象 end****************/
                if(order == null){
                    logger.error("查询订单为空 订单号=" + takeNoVoResponse.getPsordnum() + ",ordResponse="+ JSON.toJSONString(ordResponse));
                    response.setResultCodeAndMessage("6000", "查询订单失败。");
                }

                String method = "yyt.message.msg.template.send";

                Map<String, Object> dataMap = new HashedMap();
                dataMap.put("user_type", "2");
                dataMap.put("to_user", order.getOpenId());
//            dataMap.put("order_no",order.getOrderNo());
                dataMap.put("platform_type", "2");
                dataMap.put("org_app_code", order.getPlatformOrgAppCode());
                dataMap.put("org_code", order.getOrgCode());
                dataMap.put("template_code", "21002");
                Map<String, Object> msgContent = new HashedMap();
                msgContent.put("first", "您已经成功取号。");
                msgContent.put("keyword1", order.getUserName());
                msgContent.put("keyword2", order.getDoctorName());
                msgContent.put("keyword3", order.getDeptName());
                msgContent.put("keyword4", order.getOrgName());
                msgContent.put("keyword5", takeNoVoResponse.getBegintime() + "~" + takeNoVoResponse.getEndtime());//就诊时间
                String remark = "排队号:" + takeNoVoResponse.getJzxh()
                        + "\n就诊地址:" + takeNoVoResponse.getJzdd()
                        + "\n发票号:" + takeNoVoResponse.getJzhm()
                        + "\n就诊卡号:" + order.getMedicalCardNo()
                        + "\n就诊说明:" + "";
                msgContent.put("remark", remark);
                dataMap.put("msg_content", JsonUtils.toJsonString(msgContent));
                Response messageResponse = MessageService.callHumpFromInternal(method, JsonUtils.toJsonString(dataMap));
                Log.i(LogScene.REGISTER_RESERVE_AUTOTAKE,"yyt.register.reg.reserve.record.autotake", LogParamType.REQUEST,order.getOrderNo(),
                        "自动取号成功 调用message模块, request=" + JsonUtils.toJsonString(dataMap));
                Log.i(LogScene.REGISTER_RESERVE_AUTOTAKE,"yyt.register.reg.reserve.record.autotake", LogParamType.RESPONSE,order.getOrderNo(),
                        "自动取号成功 调用message模块, response=" + JsonUtils.toJsonString(messageResponse));
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("取号成功调用消息模块异常:", e.getMessage());
        }
        response.setResultCodeAndMessage("0", "成功");
        return response;
    }
}
